summaryrefslogtreecommitdiffstats
path: root/src/Generating/BioGen.h
blob: cfa748ec77ef5d4be1f156a2c1de5661c339df21 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

// BioGen.h

/*
Interfaces to the various biome generators:
	- cBioGenConstant
	- cBioGenCheckerboard
	- cBioGenDistortedVoronoi
*/





#pragma once

#include "ComposableGenerator.h"
#include "../Noise.h"
#include "../VoronoiMap.h"





class cBioGenConstant :
	public cBiomeGen
{
public:
	cBioGenConstant(void) : m_Biome(biPlains) {}
	
protected:

	EMCSBiome m_Biome;

	// cBiomeGen overrides:
	virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
} ;





/// A simple cache that stores N most recently generated chunks' biomes; N being settable upon creation
class cBioGenCache :
	public cBiomeGen
{
	typedef cBiomeGen super;
	
public:
	cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize);  // Doesn't take ownership of a_BioGenToCache
	~cBioGenCache();
	
protected:

	cBiomeGen * m_BioGenToCache;
	
	struct sCacheData
	{
		int m_ChunkX;
		int m_ChunkZ;
		cChunkDef::BiomeMap m_BiomeMap;
	} ;
	
	// To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data
	int          m_CacheSize;
	int *        m_CacheOrder;  // MRU-ized order, indices into m_CacheData array
	sCacheData * m_CacheData;   // m_CacheData[m_CacheOrder[0]] is the most recently used
	
	// Cache statistics
	int m_NumHits;
	int m_NumMisses;
	int m_TotalChain;  // Number of cache items walked to get to a hit (only added for hits)
	
	virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
} ;





class cBioGenMulticache :
	public cBiomeGen
{

	typedef cBiomeGen super;

public:
	cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength);  // Doesn't take ownership of a_BioGenToCache
	~cBioGenMulticache();

protected:
	size_t          m_CachesLength;
	size_t          m_InternalCacheLength;
	std::vector<cBiomeGen*> m_Caches;

	virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
};





/// Base class for generators that use a list of available biomes. This class takes care of the list.
class cBiomeGenList :
	public cBiomeGen
{
	typedef cBiomeGen super;
	
protected:
	// List of biomes that the generator is allowed to generate:
	typedef std::vector<EMCSBiome> EMCSBiomes;
	EMCSBiomes m_Biomes;
	int        m_BiomesCount;  // Pulled out of m_Biomes for faster access
	
	/// Parses the INI file setting string into m_Biomes.
	void InitializeBiomes(const AString & a_Biomes);
} ;





class cBioGenCheckerboard :
	public cBiomeGenList
{
	typedef cBiomeGenList super;
	
protected:
	int m_BiomeSize;
	
	// cBiomeGen overrides:
	virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
} ;





class cBioGenVoronoi :
	public cBiomeGenList
{
	typedef cBiomeGenList super;
	
public:
	cBioGenVoronoi(int a_Seed) :
		m_Voronoi(a_Seed)
	{
	}
	
protected:
	cVoronoiMap m_Voronoi;
	
	// cBiomeGen overrides:
	virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
	
	EMCSBiome VoronoiBiome(int a_BlockX, int a_BlockZ);
} ;





class cBioGenDistortedVoronoi :
	public cBiomeGenList
{
	typedef cBiomeGenList super;
	
public:
	cBioGenDistortedVoronoi(int a_Seed) :
		m_Noise(a_Seed),
		m_Voronoi(a_Seed),
		m_CellSize(0)
	{
	}

protected:
	/// Noise used for the distortion
	cNoise m_Noise;
	
	/// The underlying Voronoi map of the biomes
	cVoronoiMap m_Voronoi;
	
	/// Size of the Voronoi cells, also used for distortion amplitude
	int m_CellSize;
	
	// cBiomeGen overrides:
	virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
	
	/// Distorts the coords using a Perlin-like noise
	void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ);
} ;





class cBioGenMultiStepMap :
	public cBiomeGen
{
	typedef cBiomeGen super;
	
public:
	cBioGenMultiStepMap(int a_Seed);
	
protected:
	// Noises used for composing the perlin-noise:
	cNoise m_Noise1;
	cNoise m_Noise2;
	cNoise m_Noise3;
	cNoise m_Noise4;
	cNoise m_Noise5;
	cNoise m_Noise6;
	
	int    m_Seed;
	int    m_OceanCellSize;
	int    m_MushroomIslandSize;
	int    m_RiverCellSize;
	double m_RiverWidthThreshold;
	float  m_LandBiomesSize;
	
	typedef int    IntMap[17 * 17];  // x + 17 * z, expected trimmed into [0..255] range
	typedef double DblMap[17 * 17];  // x + 17 * z, expected trimmed into [0..1] range
		
	// cBiomeGen overrides:
	virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
	
	/** Step 1: Decides between ocean, land and mushroom, using a DistVoronoi with special conditions and post-processing for mushroom islands
	Sets biomes to biOcean, -1 (i.e. land), biMushroomIsland or biMushroomShore
	*/
	void DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap);
	
	/** Step 2: Add rivers to the land
	Flips some "-1" biomes into biRiver
	*/
	void AddRivers(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap);
	
	/** Step 3: Decide land biomes using a temperature / humidity map; freeze ocean / river in low temperatures.
	Flips all remaining "-1" biomes into land biomes. Also flips some biOcean and biRiver into biFrozenOcean, biFrozenRiver, based on temp map.
	*/
	void ApplyTemperatureHumidity(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap);
	
	/// Distorts the coords using a Perlin-like noise, with a specified cell-size
	void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ, int a_CellSize);
	
	/// Builds two Perlin-noise maps, one for temperature, the other for humidity. Trims both into [0..255] range
	void BuildTemperatureHumidityMaps(int a_ChunkX, int a_ChunkZ, IntMap & a_TemperatureMap, IntMap & a_HumidityMap);
	
	/// Flips all remaining "-1" biomes into land biomes using the two maps
	void DecideLandBiomes(cChunkDef::BiomeMap & a_BiomeMap, const IntMap & a_TemperatureMap, const IntMap & a_HumidityMap);
	
	/// Flips biOcean and biRiver into biFrozenOcean and biFrozenRiver if the temperature is too low
	void FreezeWaterBiomes(cChunkDef::BiomeMap & a_BiomeMap, const IntMap & a_TemperatureMap);
} ;





class cBioGenTwoLevel :
	public cBiomeGen
{
	typedef cBiomeGen super;
	
public:
	cBioGenTwoLevel(int a_Seed);
	
protected:
	/// The Voronoi map that decides the groups of biomes
	cVoronoiMap m_VoronoiLarge;
	
	/// The Voronoi map that decides biomes inside individual biome groups
	cVoronoiMap m_VoronoiSmall;
	
	/// The noise used to distort the input X coord
	cPerlinNoise m_DistortX;
	
	/// The noise used to distort the inupt Z coord
	cPerlinNoise m_DistortZ;
	
	cNoise m_Noise1;
	cNoise m_Noise2;
	cNoise m_Noise3;
	cNoise m_Noise4;
	cNoise m_Noise5;
	cNoise m_Noise6;


	// cBiomeGen overrides:
	virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
	virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;

	/// Selects biome from the specified biome group, based on the specified index.
	/// Note that both params may overflow
	/// a_DistLevel is either 0 or 1; zero when it is at the edge of the small Voronoi cell, 1 near the center
	EMCSBiome SelectBiome(int a_BiomeGroup, int a_BiomeIdx, int a_DistLevel);
} ;